package com.kehutong.tag.service;

import com.kehutong.common.entity.Root;
import com.kehutong.crm.entity.Tag;
import com.kehutong.crm.enums.TagSourceType;
import com.kehutong.tag.dao.UserTagDao;
import com.kehutong.tag.entity.TemplateTag;
import org.coraframework.authz.Subject;
import org.coraframework.inject.Inject;
import org.coraframework.json.JSONObject;
import org.coraframework.logger.Logger;
import org.coraframework.logger.LoggerFactory;
import org.coraframework.mvc.http.Bean;
import org.coraframework.mvc.http.ReqMapping;
import org.coraframework.mvc.http.result.Result;
import org.coraframework.mvc.webservice.WebService;
import org.coraframework.orm.jdbc.JdbcSession;
import org.coraframework.orm.jdbc.Page;
import org.coraframework.orm.jdbc.execute.Condition;
import org.coraframework.orm.jdbc.execute.PageCondition;
import org.coraframework.orm.jdbc.execute.QueryCondition;
import org.coraframework.orm.jdbc.execute.entity.FindPage;
import org.coraframework.util.IDGenerate;
import org.coraframework.util.Objects;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 企微标签服务类
 *
 * @author: liukunlong
 * @date: 2021-07-28 10:08
 */
@WebService("/crm/corp/tag/service")
public class ThirdPartyTagService {

    static final Logger logger = LoggerFactory.getLogger(ThirdPartyTagService.class);


    @Inject
    private JdbcSession jdbcSession;

    @Inject
    private UserTagDao userTagDao;


    /**
     * 根据规则产生第三方标签标志
     * @param corpNo
     * @param type
     * @param name
     * @return
     */
    public static String toKhtId(String corpNo,String type,String name) {
        String thirdPartySource="1";
        StringBuilder buf = new StringBuilder(corpNo).append("_")
                .append(thirdPartySource).append("_")
                .append(type).append("_")
                .append(name.toUpperCase());
        return Subject.encrypt(buf.toString());
    }


    /**
     * 根据条件获取标签列表
     *
     * @param jsonObject 查询对象
     * @return 标签列表
     * @throws IOException 操作异常
     */
    @ReqMapping("/page")
    public Page<Tag> page(JSONObject jsonObject) throws Exception {
        String tagName = jsonObject.getString("tagName");

        Page<Tag> result = null;
        FindPage<Tag> findPage = jdbcSession.findPage(Tag.class)
                .eq(jsonObject, "id", "pid")
                .like(jsonObject, "name")
                .eq("group", false)
                .eq("deleted", false)
                .order("sort", "desc")
                .page(jsonObject);
        result = findPage.exe();
        if (logger.isDebugEnabled()) {
            logger.debug("result:" + result);
        }
        if (Objects.nonNull(result)) {
            List<Tag> thirdPartyTagList = result.getList();
            //设置标签的标签组名称及使用标签用户数
            for (Tag thirdPartyTag : thirdPartyTagList) {
                QueryCondition query = Condition.createQuery(false);
                query.eq("deleted", false);
                query.order("createTime","desc");
                query.eq("tagNo", thirdPartyTag.getId());
                Map<String,Object> countMap = userTagDao.getUserTagCount(query);
                thirdPartyTag.setUseCount(Long.parseLong(String.valueOf(countMap.get("count"))));
                Tag thirdPartyTagGroup = jdbcSession.findById(Tag.class, thirdPartyTag.getPid());
                if (Objects.nonNull(thirdPartyTagGroup)) {
                    thirdPartyTag.setPname(thirdPartyTagGroup.getName());
                } else {
                    thirdPartyTag.setPname("");
                }
            }
        }
        return result;
    }

    /**
     * 获取标签列表
     *
     * @param jsonObject 查询对象
     * @return
     * @throws Exception
     */
    @ReqMapping("/list")
    public Object list(JSONObject jsonObject) throws Exception {
        jsonObject.put("pageNo", 1);
        jsonObject.put("pageSize", Short.MAX_VALUE);
        Page<Tag> page = page(jsonObject);
        return page.getList();
    }

    /**
     * 获取标签内容
     *
     * @param thirdPartyTag 标签对象
     * @return
     */
    @ReqMapping("/get")
    public Object get(Tag thirdPartyTag) {
        return thirdPartyTag;
    }

    /**
     * 保存标签
     *
     * @param thirdPartyTag 系统标签对象
     * @return
     */
    @Bean(newInstance = true, copy = true)
    @ReqMapping("/save")
    public Object save(Tag thirdPartyTag) {
        String id = thirdPartyTag.getId();
        Tag dbTag = jdbcSession.findOne(Tag.class)
                .eq("deleted", false)
                .eq("group", false)
                .markBegin()
                .eq("id", id).or()
                .eq("name", thirdPartyTag.getName()).or()
                .markEnd().exe();
        thirdPartyTag.setType(TagSourceType.THIRD_PARTY_TAG);
        if (Objects.isNull(dbTag)) {
            thirdPartyTag.setGroup(false);
            thirdPartyTag.setSort(System.currentTimeMillis());
            thirdPartyTag.setCreateBy(Root.ROOT_ID);
            thirdPartyTag.setCreateName("系统");
            jdbcSession.insert(thirdPartyTag);
        } else {
            dbTag.setName(thirdPartyTag.getName());
            thirdPartyTag.setCreateBy(Root.ROOT_ID);
            thirdPartyTag.setCreateName("系统");
            jdbcSession.updateById(dbTag);
        }
        return Result.success();
    }

    /**
     * 更新标签组及标签
     *
     * @param thirdPartyTag 系统标签对象
     * @return
     * @throws Exception
     */
    @Bean(copy = true)
    @ReqMapping("/update")
    public Object update(Tag thirdPartyTag) throws Exception {
        String id = thirdPartyTag.getId();
        Tag dbTag = jdbcSession.findOne(Tag.class)
                .eq("group", false)
                .eq("deleted", false)
                .eq("id",id).exe();
        if (Objects.isNull(dbTag)) {
            return Result.success("0", "标签不存在");
        }
        jdbcSession.updateById(thirdPartyTag);
        return Result.success();
    }


    /**
     * 删除标签
     *
     * @param thirdPartyTag 标签对象
     * @return
     */
    @ReqMapping("/delete")
    public Object delete(Tag thirdPartyTag) {
        thirdPartyTag.setDeleted(true);
        jdbcSession.updateById(thirdPartyTag);
        return Result.success();
    }

    /**
     * 根据条件获取标签组分页列表
     *
     * @param jsonObject 查询对象
     * @return 住户汽车列表
     * @throws IOException 操作异常
     */
    @ReqMapping("/group/page")
    public Page<Tag> groupPage(JSONObject jsonObject) throws Exception {
        String tagName = jsonObject.getString("tagName");

        Page<Tag> result = null;
        FindPage<Tag> findPage = jdbcSession.findPage(Tag.class)
                .eq(jsonObject, "id")
                .like(jsonObject, "name")
                .eq("group", true)
                .eq("deleted", false)
                .order("sort", "desc")
                .page(jsonObject);
        if (Objects.nonEmpty(tagName)) {
            List<Tag> thirdPartyTagList = jdbcSession.findArray(Tag.class)
                    .eq("group", false)
                    .eq("deleted", false)
                    .like("name", tagName).exe();
            List<String> ids = thirdPartyTagList.stream().map(Tag::getPid).collect(Collectors.toList());
            if (Objects.nonEmpty(ids)) {
                findPage.in("id", ids);
            }
        }
        result = findPage.exe();
        if (logger.isDebugEnabled()) {
            logger.debug("result:" + result);
        }
        if (Objects.nonNull(result)) {
            List<Tag> thirdPartyTagGroupList = result.getList();
            for (Tag thirdPartyGroupTag : thirdPartyTagGroupList) {
                List<Tag> thirdPartyTagList = jdbcSession.findArray(Tag.class)
                        .eq("pid", thirdPartyGroupTag.getId())
                        .eq("group", false)
                        .eq("deleted", false)
                        .order("sort", "desc")
                        .exe();

                //设置标签的组名称
                for (Tag thirdPartyTag : thirdPartyTagList) {
                    thirdPartyTag.setPname(thirdPartyGroupTag.getName());
                }
                thirdPartyGroupTag.setChildList(thirdPartyTagList);

            }
        }
        return result;
    }

    /**
     * 根据条件获取标签组列表
     *
     * @param jsonObject 查询对象
     * @return
     * @throws Exception
     */
    @ReqMapping("/group/list")
    public Object groupList(JSONObject jsonObject) throws Exception {
        jsonObject.put("pageNo", 1);
        jsonObject.put("pageSize", Short.MAX_VALUE);
        Page<Tag> page = groupPage(jsonObject);
        return page.getList();
    }

    /**
     * 获取标签组
     *
     * @param thirdPartyTagGroup 系统标签对象
     * @return
     */
    @ReqMapping("/group/get")
    public Object groupGet(Tag thirdPartyTagGroup) {
        if (Objects.nonNull(thirdPartyTagGroup)) {
            List<Tag> thirdPartyTagList = jdbcSession.findArray(Tag.class)
                    .eq("pid", thirdPartyTagGroup.getId())
                    .eq("group", false)
                    .eq("deleted", false)
                    .order("sort", "desc")
                    .exe();
            thirdPartyTagGroup.setChildList(thirdPartyTagList);

        }
        return thirdPartyTagGroup;
    }

    /**
     * 保存标气标签组及标签
     *
     * @param thirdPartyTagGroup 系统标签对象
     * @return
     */
    @Bean(newInstance = true, copy = true)
    @ReqMapping("/group/save")
    public Object groupSave(Tag thirdPartyTagGroup) {
        String id = thirdPartyTagGroup.getId();
        Tag dbTagGroup = jdbcSession.findOne(Tag.class)
                .eq("deleted", false)
                .eq("group", true)
                .markBegin()
                .eq("id", id).or()
                .eq("name", thirdPartyTagGroup.getName()).or()
                .markEnd().exe();
        thirdPartyTagGroup.setType(TagSourceType.THIRD_PARTY_TAG);
        if (Objects.isNull(dbTagGroup)) {
            thirdPartyTagGroup.setPid(Root.ROOT_ID);
            thirdPartyTagGroup.setGroup(true);
            thirdPartyTagGroup.setSort(System.currentTimeMillis());
            jdbcSession.insert(thirdPartyTagGroup);
        } else {
            throw new RuntimeException("标签组不能重复");
/*            dbTagGroup.setName(thirdPartyTagGroup.getName());
            jdbcSession.updateById(dbTagGroup);*/
        }
        List<Tag> thirdPartyTagList = thirdPartyTagGroup.getChildList();
        if (Objects.nonNull(thirdPartyTagList)) {
            for (Tag thirdPartyTag : thirdPartyTagList) {
                String tagId=toKhtId(thirdPartyTagGroup.getCompanyNo(),"TAG",thirdPartyTag.getName());
                thirdPartyTag.setId(tagId);
                thirdPartyTag.setPid(thirdPartyTagGroup.getId());
                thirdPartyTag.setGroup(false);
                thirdPartyTag.setType(TagSourceType.THIRD_PARTY_TAG);
                thirdPartyTag.setCreateBy(Root.ROOT_ID);
                thirdPartyTag.setCreateName("系统");
            }
        }
        jdbcSession.insert(thirdPartyTagList);
        return Result.success();
    }

    /**
     * 更新标签组及标签
     *
     * @param thirdPartyTagGroup 系统标签对象
     * @return
     * @throws Exception
     */
    @Bean(copy = true)
    @ReqMapping("/group/update")
    public Object groupUpdate(Tag thirdPartyTagGroup) throws Exception {
        String id = thirdPartyTagGroup.getId();
        Tag dbTagGroup = jdbcSession.findOne(Tag.class)
                .eq("deleted", false)
                .markBegin()
                .eq("id", id).or()
                .eq("name", thirdPartyTagGroup.getName()).or()
                .markEnd().exe();
        if (Objects.isNull(dbTagGroup)) {
            return Result.success("0", "标签组不存在");
        }
        jdbcSession.updateById(thirdPartyTagGroup);


        //输入的标签集合
        List<Tag> thirdPartyTagList = thirdPartyTagGroup.getChildList();

        Map<String, Tag> mapping =new HashMap<>();
        for(Tag thirdPartyTag:thirdPartyTagList){
            if(Objects.nonEmpty(thirdPartyTag.getId())){
                mapping.put(thirdPartyTag.getId(),thirdPartyTag);
            }
        }


        //数据库已存在的标签集合
        List<Tag> dbTagList = jdbcSession.findArray(Tag.class)
                .eq("pid", dbTagGroup.getId())
                .eq("group", false)
                .eq("deleted", false)
                .order("sort", "desc")
                .exe();


        //需要更新的标签集合
        List<Tag> updateTagList = new ArrayList<>();

        //需要删除的标签集合
        List<Tag> deleteTagList = new ArrayList<>();

        for (Tag dbTag : dbTagList) {
            String dbId = dbTag.getId();
            if (mapping.containsKey(dbId)) {
                updateTagList.add(mapping.get(dbId));
                thirdPartyTagList.remove(dbTag);
            } else {
                deleteTagList.add(dbTag);
            }
        }

        //需要新增的标签集合
        List<Tag> addTagList = new ArrayList<>(thirdPartyTagList);

        //增量新增标签
        if (Objects.nonEmpty(addTagList)) {
            for (Tag thirdPartyTag : addTagList) {
                String tagId=toKhtId(thirdPartyTagGroup.getCompanyNo(),"TAG",thirdPartyTag.getName());
                thirdPartyTag.setId(tagId);
                thirdPartyTag.setPid(dbTagGroup.getId());
                thirdPartyTag.setGroup(false);
                thirdPartyTag.setType(TagSourceType.THIRD_PARTY_TAG);
                thirdPartyTag.setCreateBy(Root.ROOT_ID);
                thirdPartyTag.setCreateName("系统");
            }
            jdbcSession.insert(addTagList);
        }

        //增量更新标签
        if (Objects.nonEmpty(updateTagList)) {
            jdbcSession.updateById(updateTagList);
        }

        //增量删除标签
        if (Objects.nonEmpty(deleteTagList)) {
            for (Tag thirdPartyTag : deleteTagList) {
                thirdPartyTag.setDeleted(true);
            }
            jdbcSession.updateById(deleteTagList);
        }
        return Result.success();
    }


    /**
     * 删除标签组及标签
     *
     * @param thirdPartyTagGroup 系统标签组对象
     * @return
     */
    @ReqMapping("/group/delete")
    public Object groupDelete(Tag thirdPartyTagGroup) {
        thirdPartyTagGroup.setDeleted(true);
        jdbcSession.updateById(thirdPartyTagGroup);
        if (thirdPartyTagGroup.isGroup()) {
            List<Tag> thirdPartyTagList = jdbcSession.findArray(Tag.class)
                    .eq("pid", thirdPartyTagGroup.getId())
                    .eq("group", false)
                    .eq("deleted", false)
                    .order("sort", "desc")
                    .exe();
            if (Objects.nonEmpty(thirdPartyTagList)) {
                for (Tag thirdPartyTag : thirdPartyTagList) {
                    thirdPartyTag.setDeleted(true);
                }
                jdbcSession.updateById(thirdPartyTagList);
            }
        }
        return Result.success();
    }


}
